import asyncio
import websockets
import time
import json
import threading
from common import utils

# 存储所有的客户端
Clients = []

class Server():
    def __init__(self):
        self.observers = set()
        self.allStocks = {}
        self.flowRank = []

    # 发消息给客户端的回调函数
    async def s(self,msg,websocket=None):
        await self.sendMsg(msg,websocket)

    # 每一个客户端链接上来就会进一个循环
    async def listen(self, websocket, path):
        Clients.append(websocket)
        await websocket.send(json.dumps({"type": "handshake"}))
        while True:
            try:
                recv_text = await websocket.recv()
                msg = json.loads(recv_text)

                if not msg['type'] == 'observe':
                    continue

                stocks = msg['stocks']
                for stock in stocks:
                    if (stock not in self.observers):
                        self.observers.add(stock)

                if self.allStocks is not None:
                    await websocket.send(json.dumps({ "type": "notity", "data": self.filterObserved()}))

                if self.flowRank is not None:
                    await websocket.send(json.dumps({ "type": "flow", "data": self.flowRank}))

            except websockets.ConnectionClosed:
                print("ConnectionClosed...", path)  # 链接断开
                Clients.remove(websocket)
                break
            except websockets.InvalidState:
                print("InvalidState...")  # 无效状态
                Clients.remove(websocket)
                break
            except Exception as e:
                print(e)
                Clients.remove(websocket)
                break

    async def update(self, allStocks, flowRank):
        self.allStocks = allStocks
        self.flowRank = flowRank 
        if len(self.observers) == 0:
            return

        await self.broadcastMsg({ "type": "flow", "data": flowRank})
        await self.broadcastMsg({ "type": "notity", "data": self.filterObserved()})

    def filterObserved(self):
        filtered = []
        for code in self.observers:
            if code in self.allStocks:
                filtered.append(self.allStocks[code])

        return filtered

    # 发送消息
    async def sendMsg(self,msg,websocket):
        print('sendMsg:',msg)
        if websocket != None:
            await websocket.send(msg)
        else:
            await self.broadcastMsg(msg)
        # 避免被卡线程
        await asyncio.sleep(0.2)

	# 群发消息
    async def broadcastMsg(self, msg):
        jstr = json.dumps(msg)
        print('sendMsg:', jstr)
        for user in Clients:
            await user.send(jstr)

    # 启动服务器
    async def runServer(self):
        async with websockets.serve(self.listen, '0.0.0.0', 8888):
            await asyncio.Future()  # run forever

	# 多线程模式，防止阻塞主线程无法做其他事情
    def WebSocketServer(self):
        asyncio.run(self.runServer())

    def startServer(self):
        # 多线程启动，否则会堵塞
        thread = threading.Thread(target=self.WebSocketServer)
        thread.start()
        thread.join()
        print("go!!!")

    def getObervers(self):
        return self.observers
